package com.yx.changdao.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yx.changdao.common.entity.Department;
import com.yx.changdao.common.entity.SysRole;
import com.yx.changdao.common.entity.SysUser;
import com.yx.changdao.common.entity.SysUserRole;
import com.yx.changdao.common.exception.AlertException;
import com.yx.changdao.common.mapper.DepartmentMapper;
import com.yx.changdao.common.mapper.SysUserMapper;
import com.yx.changdao.common.utils.*;
import com.yx.changdao.service.DepartmentService;
import com.yx.changdao.service.SysRoleService;
import com.yx.changdao.service.SysUserRoleService;
import com.yx.changdao.service.SysUserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;
import java.util.Random;

/**
 * @Title: SysUserServiceImpl
 * @Description: 系统用户服务实现。
 * @Auther: Zhangjiashun
 * @Version: 1.0
 * @create 2019/11/6 12:16
 */
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {

    @Autowired
    private SysUserRoleService sysUserRoleService;
    @Autowired
    private RedisUtils redisUtils;
    @Autowired
    private DepartmentMapper departmentMapper;
    @Autowired
    private DepartmentService departmentService;
    @Autowired
    private SysRoleService sysRoleService;


    /**
     * 添加用户 传入 SysUser 对象
     * 必填 用户名， 密码， 昵称。
     * 密码传入明文，添加成功后返回的 SysUser 为加密后密码
     *
     * @param user 用户
     * @return 添加后的用户
     * @throws AlertException 异常
     */
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public SysUser addUser(SysUser user) throws AlertException {
        if (StringUtils.isBlank(user.getUsername())) {
            throw new AlertException("用户信息不可为空");
        }
        if (StringUtils.isBlank(user.getRoleId())) {
            throw new AlertException("角色不可为空");
        }
        Department department = departmentMapper.selectOne(new QueryWrapper<Department>().eq(Department.DEP_ID, user.getDepId()).select(Department.DEP_NAME));
        if (Objects.isNull(department)) {
            throw new AlertException("部门不存在");
        }
        user.setDepName(department.getDepName());
        SysRole sysRole = sysRoleService.getOne(new QueryWrapper<SysRole>().eq(SysRole.ROLE_ID, user.getRoleId()));
        if (Objects.isNull(sysRole)) {
            throw new AlertException("角色不存在");
        }
        if (StringUtils.isBlank(user.getPassword())) {  //设置默认密码
            user.setPassword(SysConst.SYS_DEFAULT_PASSWORD);
        }

        if (0 < this.count(new QueryWrapper<SysUser>().lambda().eq(SysUser::getUsername, user.getUsername()))) {
            throw new AlertException("账号已存在");
        }
        String salt = MD5Utils.createSalt();
        user.setSalt(salt);

        user.setPassword(MD5Utils.shiroEncryption(user.getPassword(), salt));
        this.save(user);
        //先删除用户角色,然后新增
        sysUserRoleService.remove(new QueryWrapper<SysUserRole>().eq(SysUserRole.USER_ID, user.getUserId()));
        //用户角色
        sysUserRoleService.addUserRole(user.getUserId(), user.getRoleId());
        return user;
    }

    /**
     * 通过id获取用户
     *
     * @param userId 用户id
     * @return 用户
     * @throws AlertException 异常
     */
    @Override
    public SysUser getUserById(String userId) throws AlertException {
        if (userId == null) {
            throw new AlertException("userId is null");
        }
        return this.getById(userId);
    }

    /**
     * 通过账号获取用户
     *
     * @param username 用户名
     * @return 用户
     */
    @Override
    public SysUser getUserByUsername(String username) {
        return this.getOne(new QueryWrapper<SysUser>().lambda().eq(SysUser::getUsername, username));
    }

    /**
     * 更新用户
     *
     * @return 更新后的用户
     */
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public Boolean updateUser(SysUser user) throws AlertException {
        user.setUsername(null);
        if (StringUtils.isBlank(user.getRoleId())) {
            throw new AlertException("角色不可为空");
        }
        Department department = departmentMapper.selectOne(new QueryWrapper<Department>().eq(Department.DEP_ID, user.getDepId()).select(Department.DEP_NAME));
        if (Objects.isNull(department)) {
            throw new AlertException("部门不存在");
        }
        user.setDepName(department.getDepName());
        int count = sysRoleService.count(new QueryWrapper<SysRole>().eq(SysRole.ROLE_ID, user.getRoleId()));
        if (count == 0) {
            throw new AlertException("角色不存在");
        }
        // 设置不允许更新的列。
        user.setUsername(null);
        user.setPassword(null);
        user.setSalt(null);
        user.setCreateBy(null);
        user.setStatus(null);
        user.setCreateTime(null);
        user.setDepName(department.getDepName());
        sysUserRoleService.remove(new QueryWrapper<SysUserRole>().eq(SysUserRole.USER_ID, user.getUserId()));
        SysUserRole userRole = new SysUserRole();
        userRole.setUserId(user.getUserId());
        userRole.setRoleId(user.getRoleId());
        sysUserRoleService.save(userRole);
        return updateById(user);
    }


    /**
     * 锁定用户
     *
     * @param userId 用户id
     * @return 是否成功
     * @throws AlertException 异常
     */
    @Override
    public Boolean lockUser(String userId) throws AlertException {
        SysUser user = this.getById(userId);

        List<String> userRoleIds = this.sysUserRoleService.getUserRoleIds(user.getUserId());
        for (String userRoleId : userRoleIds) {
            if (StringUtils.equals(userRoleId, SysConst.SYS_ROLE)) {
                throw new AlertException("不能锁定管理员账户");
            }
        }
        this.update(new UpdateWrapper<SysUser>()
                .eq(SysUser.USER_ID, userId)
                .set(SysUser.STATUS, user.getStatus() == 0 ? 1 : 0));
        return user.getStatus() == 1;


    }

//    /**
//     * 解锁用户
//     *
//     * @param userId
//     * @return
//     * @throws AlertException
//     */
//    @Override
//    public SysUser unLockUser(String userId) throws AlertException {
//        SysUser user = this.getUserById(userId);
//        user.setStatus(1);
//        boolean b = this.updateById(user);
//        if (!b) {
//            throw new AlertException("解锁用户失败");
//        }
//        return user;
//    }

    /**
     * 修改密码
     *
     * @param userId   用户id
     * @param password 密码
     * @return 修改以后的用户
     * @throws AlertException 异常
     */
    @Override
    public SysUser changePwd(String userId, String password) throws AlertException {
        if (StringUtils.isBlank(password)) {
            throw new AlertException("密码不可为空");
        }
        String salt = MD5Utils.createSalt();
        SysUser user = this.getUserById(userId);
        user.setSalt(salt);
        user.setPassword(MD5Utils.shiroEncryption(password, salt));
        boolean b = this.updateById(user);
        if (!b) {
            throw new AlertException("密码修改失败");
        }
        return user;
    }

    /**
     * 根据id删除用户
     *
     * @param userId 用户id
     * @return 是否删除成功
     */
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public Boolean delUser(String userId) {
        // 删除用户前先删除 用户对应的所有权限。
        this.sysUserRoleService.delUserAllPermission(userId);
        return this.removeById(userId);
    }

    /**
     * 获取token
     *
     * @param user 用户
     * @return 用户token
     */
    @Override
    public String generateJwtToken(SysUser user) {
        // 返回生成的Token
        long time = SpringContextUtils.getAppConfig("jwt.time", Long.class, -1L);
        String sign = JwtUtils.sign(JwtUtils.setJwt(user), user.getSalt(), time);
        this.redisUtils.set(SysConst.USER_FIX + user.getUserId(), sign, time);
        return sign;
    }

    /**
     * 删除token
     *
     * @param userId 用户id
     */
    @Override
    public void deleteLoginInfo(String userId) {
        this.redisUtils.del(SysConst.USER_FIX + userId);
    }

    /**
     * 获取登录用户信息
     *
     * @param userId 用户id
     * @return 用户
     */
    @Override
    public SysUser getJwtTokenInfo(String userId, String token) throws AlertException {

        String reidsToken = this.redisUtils.getString(SysConst.USER_FIX + userId);

        if (reidsToken == null) {
            return null;
        }

        if (!StringUtils.equals(token, reidsToken)) {
            return null;
        }

        return this.getUserById(userId);
    }

    /**
     * 批量新增用户
     *
     * @return
     * @throws AlertException
     */
    @Override
    public Boolean saveBatchUser(String zkgl, String zkpt, String zxgl, String zxpt) throws AlertException {
        List<Department> list = departmentService.list();
        for (Department department : list) {
            if (department.getDepId() == 20) {
                for (int i = 1; i <= 7; i++) {
                    if (i == 1) {
                        addBatch(department, zkgl, i);
                    } else {
                        addBatch(department, zkpt, i);
                    }
                }
            } else {
                for (int i = 1; i <= 100; i++) {
                    if (i == 1) {
                        addBatch(department, zxgl, i);
                    } else {
                        addBatch(department, zxpt, i);
                    }
                }
            }
        }
        return true;
    }

    public void addBatch(Department department, String roleId, int i) throws AlertException {
        String userName = PinyinUtils.getPinyinFirstLetters(department.getDepName()) + i;
        String nickName = department.getDepName() + i;
        SysUser sysUser = new SysUser();
        sysUser.setUsername(userName);
        sysUser.setNickname(nickName);
        sysUser.setRoleId(roleId);
        sysUser.setDepId(department.getDepId());

        String salt = MD5Utils.createSalt();
        sysUser.setSalt(salt);

        String strNumRandom = getStrNumRandom(8);
        sysUser.setPassword(strNumRandom);
        sysUser.setOriginalPassword(strNumRandom);
        SysUser user = this.getOne(new QueryWrapper<SysUser>().eq(SysUser.USERNAME, sysUser.getUsername()));
        if (user == null) {
            SysUser user1 = addUser(sysUser);
            if (user1 == null) {
                throw new AlertException("新增失败");
            }
        } else {
            sysUser.setUserId(user.getUserId());
            Boolean aBoolean = updateUser(sysUser);
            if (aBoolean == false) {
                throw new AlertException("更新失败");
            }
        }
    }

    //密码 8位
    private  String getStrNumRandom(Integer length) {
        StringBuilder str = new StringBuilder();
        Random random = new Random();
        for (int i = 0; i < length; i++) {
            boolean b = random.nextBoolean();
            if (b) { // 字符串  
                int choice = random.nextBoolean() ? 65 : 97; //取得65大写字母还是97小写字母  
                str.append((char) (choice + random.nextInt(26)));// 取得大写字母  
            } else { // 数字  
                str.append(random.nextInt(10));
            }
        }
        String s = str.toString().toLowerCase();
        return s;
    }
}
